﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Reflection;
using System.Windows.Forms;

namespace peonwar
{
    // Gere les profils des joueurs, les ouvertures, fermetures et enregistrement de profils.
    static class SettingManager
    {
        // Profil actuel utiliser, tout les element du jeu modifiables par les configs 
        // se basent sur ce profil.
        public static Profil CurrentProfil;
        public static List<Profil> ProfilList;
        public static int ProfilIndex;
        public static int ProfilIndexMax;
        public static int SelectedProfil;
        public static int DisplayOffset;
        public static string GamePath = Path.GetDirectoryName(Application.ExecutablePath) + "/";

        // Profil par defaut
        public static Profil Default;

        public static void Initialize()
        {
            // Creer le profil par defaut
            Default = new Profil();
            SetDefaultValues(ref Default, true, true);
        }

        public static void SetDefaultValues(ref Profil prof, bool defaultname, bool setlanguage)
        {
            if (defaultname)
                prof.Name = "DEFAULT";

            SetDefaultConfigs(ref prof, setlanguage);

            prof.Winz = 0;
            prof.Failz = 0;
            prof.Progress = 1;
            prof.Playtime = 0;
            prof.Drawz = 0;
            prof.Character = Perso.None;
        }

        public static void SetDefaultConfigs(ref Profil prof, bool setlanguage)
        {
            prof.Fullscreen = false;
            prof.SoundVol = 5;
            prof.MusicVol = 5;
            prof.QuakeVol = 5;
            prof.Quake = 0;
            if (setlanguage)
                prof.Localization = Language.English;
            prof.Particles = true;
            prof.Blood = true;
            prof.Pan = true;
            prof.Sens = 2;
            prof.Starter = true;
            prof.TailleCursor = 1;
            prof.Color1Cursor = Color.Yellow;
            prof.Color2Cursor = Color.Red;
            prof.TypeCursor = "+";
            prof.Chatdelay = 3;
            prof.Bindings = new List<string>();
            prof.azerty = false ;
            prof.video = true;
            List<int> newlist = new List<int>();
            while (newlist.Count() < AchievementManager.AchivementCount)
                newlist.Add(0);
            prof.AchievementList = newlist;
        }

        // Sauvegarde le current profil dans son fichier associer (met a jour)
        // Et place le nom de ce profil en tete du "profils.txt" pour le considerer
        // comme dernier profil utiliser (donc a charger au reboot du jeu)
        public static void SaveCurrentProfilFile()
        {
            if (CurrentProfil == Default)
                return;

            // Sauvegarde le current profil dans son fichier associer
            try
            {
                // Ecrit le profil en clair dans le fichier temp
                StreamWriter writer1 = new StreamWriter(File.Open(GamePath + "Content/Profils/temp", FileMode.Create, FileAccess.Write));
                XmlSerializer xml = new XmlSerializer(typeof(Profil));
                xml.Serialize(writer1, CurrentProfil);
                writer1.Close();

                // Lit le profil en clair et le crypt dans le fichier du profil
                Security.WriteCipher(CurrentProfil.Name);

            }
            catch
            {
                Console.WriteLine("Error in writing the profil file");
                Console.WriteLine("Profil hasn't been saved");
                return;
            }

            // Et place le nom de ce profil en tete du "profils.txt" pour le considerer
            // comme dernier profil utiliser (donc a charger au reboot du jeu)
            SetCurrentProfil();
        }

        // Place juste le nom du current profil en tete du "profils.txt" pour le considerer
        // comme dernier profil utiliser (donc a charger au reboot du jeu)
        public static void SetCurrentProfil()
        {
            try
            {
                StreamWriter stream2 = new StreamWriter(File.Open(GamePath + "Content/Profils/profils.txt", FileMode.Create, FileAccess.Write));
                if (CurrentProfil != Default)
                    stream2.WriteLine(CurrentProfil.Name); // Ecrit en tete du fichier le nom du profil en cours
                foreach (Profil p in ProfilList)       // Ecrit le reste des profils sans reecrire le profil en cours
                {
                    if (p.Name != CurrentProfil.Name && p != Default)
                        stream2.WriteLine(p.Name);
                }
                stream2.Close();
            }
            catch
            {
                Console.WriteLine("Profil list not found");
                Console.WriteLine("Current profil hasn't been updated in the profil list as the new starting profil");
                return;
            }
        }

        // Charge tout les profils et set le premier de la liste comme le current profil
        public static void LoadProfilList()
        {
            ProfilList = new List<Profil> { };

            List<string> namelist = new List<string> { };

            try
            {
                Console.WriteLine(GamePath + "Content/Profils/profils.txt");
                string pa = GamePath + "Content/Profils/profils.txt";
                StreamReader reader1 = new StreamReader(File.Open(pa, FileMode.OpenOrCreate, FileAccess.Read));
                string line;
                while ((line = reader1.ReadLine()) != null)
                {
                    namelist.Add(line);
                }
                reader1.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Profil list not found, default profil loaded");
                Console.WriteLine(e.Message);
                ProfilList.Add(Default);
                CurrentProfil = ProfilList[0];
                return;
            }

            if (namelist.Count() == 0)
            {
                Console.WriteLine("Profil list empty, default profil loaded");

                ProfilList.Add(Default);
                CurrentProfil = ProfilList[0];
                return;
            }

            for (int i = 0; i < namelist.Count(); i++)
            {
                Security.ReadDecipher(namelist[i]);

                StreamReader reader2 = new StreamReader(File.Open(GamePath + "Content/Profils/temp", FileMode.Open, FileAccess.Read));
                XmlSerializer xml = new XmlSerializer(typeof(Profil));
                ProfilList.Add((Profil)xml.Deserialize(reader2));
                reader2.Close();
                File.Delete(GamePath + "Content/Profils/temp");
            }
            ProfilList.Add(Default);

            ProfilIndexMax = ProfilList.Count() - 1;
            SelectedProfil = 0;
            DisplayOffset = 0;
            ProfilIndex = SelectedProfil;
            CurrentProfil = ProfilList[ProfilIndex];
        }

        public static void NextProfil()
        {
            if (SelectedProfil + 1 <= ProfilIndexMax)
                SelectedProfil++;

            if (SelectedProfil > 3 && SelectedProfil - 3 > DisplayOffset)
                DisplayOffset++;
        }

        public static void PreviousProfil()
        {
            if (SelectedProfil - 1 >= 0)
                SelectedProfil--;

            if (SelectedProfil < DisplayOffset)
                DisplayOffset--;
        }

        // Defini le selected profil comme le current profil
        public static void LoadProfil()
        {
            ProfilIndex = SelectedProfil;
            CurrentProfil = ProfilList[ProfilIndex];
            DevConsole.LoadBindings();
            SetCurrentProfil();
            AchievementManager.Initialize();
            AchievementManager.AchievementGet();
        }

        // Efface le profil actuel et set le next profil comme le current profil
        public static void DeleteSelectedProfil()
        {
            File.Delete(GamePath + "Content/Profils/" + ProfilList[SelectedProfil].Name);


            ProfilList.RemoveAt(SelectedProfil);
            ProfilIndexMax--;
            SelectedProfil = 0;
            DisplayOffset = 0;
            ProfilIndex = SelectedProfil;
            CurrentProfil = ProfilList[ProfilIndex];

            SetCurrentProfil();
        }

        public static void CreateProfil(string name, Perso p)
        {
            Profil newprofil = new Profil();

            SetDefaultValues(ref newprofil, false, false);
            newprofil.Name = name;

            newprofil.Fullscreen = CurrentProfil.Fullscreen;
            newprofil.Localization = CurrentProfil.Localization;
            newprofil.MusicVol = CurrentProfil.MusicVol;
            newprofil.SoundVol = CurrentProfil.SoundVol;
            newprofil.Character = p;

            ProfilList.Add(newprofil);
            ProfilIndexMax++;
            CurrentProfil = ProfilList[ProfilList.Count() - 1];

            SaveCurrentProfilFile();
        }

        public static void ClearList()
        {
            CurrentProfil = Default;
            for (int i = 0; i < ProfilList.Count(); i++)
            {
                if (ProfilList[i].Name != Default.Name)
                {
                    File.Delete(GamePath + "Content/Profils/" + ProfilList[i].Name);
                }
            }
            ProfilList.Clear();
            ProfilList.Add(Default);
            ProfilIndexMax = 0;
            SelectedProfil = 0;
            DisplayOffset = 0;
            ProfilIndex = 0;

            SetCurrentProfil();
        }

        public static void SetDefaultProfil()
        {
            for (int i = 0; i < ProfilList.Count(); i++)
            {
                if (ProfilList[i].Name == Default.Name)
                {
                    SelectedProfil = i;
                    LoadProfil();
                    break;
                }
            }
        }
    }
}
